home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
COMM
/
INTERNET
/
TELNET
/
RLOGIND
/
!RloginD
/
telnet
/
rxtelnet_c
< prev
next >
Wrap
Text File
|
1993-09-02
|
7KB
|
333 lines
/* > rxtelnet.c
** (C) 1993 Andrew Brooks, arb@comp.lancs.ac.uk
** 7 Kennedy Close, Newton, Chester, CH2 2PL.
** Version 1.50 - Thu 02 Sep 11:52:11 WET DST 1993
**
** Full-duplex remote-login server
** Understands very limited set of telnet commands.
** Sends logout command when connection is dropped.
** Option LOG_CHARS to log all chars passing through in both directions.
** Option ESCAPED_CHARS to recognise escaped control chars from remote host.
** Option STRIP14 to strip character 14 from Archimedes (Enable Paged Mode)
** which messes up some terminal emulators.
** Option DEL2BS to convert Delete to Backspace (127 to 8).
** Program can be quit using Ctrl-C only when no clients are connected.
*/
static char SCCSid[] = "@(#)rxtelnet.c 1.50 (C) 1993 arb RLoginD telnet server";
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#ifdef SIGCLD
#define SIGCHILD SIGCLD
#endif
#ifdef SIGCHLD
#define SIGCHILD SIGCHLD
#endif
#include "term.h"
TERM_STRUCT termbuf;
#define EXIT(A) { atexit(); exit(A); }
#define ERR_FILE "rx_log"
#define ESCAPE 27
#define DEL 127
#define BS 8
#define CMD_LOGOUT 2
#ifdef LOG_CHARS
#define PR(x) (isascii(x)&&isprint(x)?x:'.')
void
log_char(fname, ch)
char *fname;
unsigned int ch;
{
FILE *fp=fopen(fname,"a");
if (fp==NULL) fprintf(stderr,"Warning: could not open file %s\n",fname);
else
{
fprintf(fp,"%s: %c %8x %d\n",fname, PR(ch), ch, ch);
fclose(fp);
}
}
#endif
void
reap()
{
wait();
}
void
atexit()
{
/* called just before exit() */
/* restore old terminal state */
Term_Restore(0,&termbuf);
}
void
quit()
/* called when program interrupted, eg. ^C */
{
fprintf(stderr,"Quit...\n"); /* goes to log file */
EXIT(1);
}
int
read_from_socket(sock, buf)
int sock;
char *buf;
{
int num;
/* reads one byte, returns number of bytes read (ie. 1 if successful) */
num=read(sock,buf,1);
if (num<1)
{
if (num!=0)
perror("Cannot read from remote login user socket");
else
fprintf(stderr,"Remote user logged out\n");
close(sock);
num=0;
}
#ifdef LOG_CHARS
log_char("toarc_log", *buf);
#endif
return(num);
}
int
write_to_stdout(buf)
char *buf;
{
int num;
num = write(1,buf,1);
if (num<1)
{
perror("Cannot write to remote machine");
num=0;
}
return(num);
}
int
read_from_stdin(buf)
char *buf;
{
/* read from remote machine. strip esc and add 32 to following char */
int num;
num = read(0,buf,1);
#ifdef DEL2BS
if (*buf == DEL) *buf = BS;
#endif
if (num<1)
{
perror("Cannot read from remote machine's kbd");
num=0;
}
#ifdef ESCAPED_CHARS
else if (*buf == ESCAPE)
{
num = read(0,buf,1);
if (num<1)
{
perror("Cannot read from remote machine's kbd");
num=0;
}
*buf = (*buf)+32;
}
#endif
#ifdef LOG_CHARS
log_char("fromarc_log", *buf);
#endif
return(num);
}
int
write_to_socket(sock, buf)
int sock;
char *buf;
{
int num;
#ifdef STRIP14
if (*buf == 14) return(1);
#endif
num = write(sock, buf, 1);
if (num<1)
{
perror("Cannot write to remote login user socket");
num=0;
}
return(num);
}
void
telnet_command(cmd)
int cmd;
{
switch (cmd)
{
case 1:
fprintf(stderr,"Telnet command 1\n");
break;
case 3:
fprintf(stderr,"Telnet command 3\n");
break;
default:
fprintf(stderr,"Unknown telnet command\n");
break;
}
}
int
main(argc,argv)
int argc;
char* argv[];
{
int sock, newsock; /* wait and connection sockets */
struct sockaddr_in server; /* sock details */
struct sockaddr_in from; /* newsock (client) details */
int fromLength; /* length of from */
int child; /* child's process id */
int errfd; /* error log file descriptor */
unsigned char inbyte[2], outbyte[2]; /* input and output bytes */
struct hostent *remotehost;
char *remotehostname;
Term_Save(0,&termbuf);
signal(SIGHUP, quit);
signal(SIGINT, quit);
signal(SIGQUIT, quit);
signal(SIGTERM, quit);
signal(SIGCHILD, reap);
Term_NoEcho(0);
if (argc!=1)
{
fprintf(stderr,"%s: Archimedes telnet server - no paramaters\n");
EXIT(1);
}
sock=socket(AF_INET,SOCK_STREAM,0);
if (sock<0)
{
perror("Cannot create socket");
EXIT(1);
}
server.sin_family=AF_INET;
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons((unsigned long)PORT);
if (bind(sock,(struct sockaddr*)&server,sizeof server)<0)
{
perror("Cannot open socket");
EXIT(1);
}
if (listen(sock,0)==-1)
{
perror("Cannot listen for connections");
EXIT(1);
}
errfd=open(ERR_FILE,O_WRONLY | O_CREAT,0644);
if (errfd<0)
{
perror("Cannot open error log");
EXIT(1);
}
fprintf(stderr,"%s: logging error messages to file %s\n",argv[0],ERR_FILE);
dup2(errfd,2); /* errs -> log file */
fprintf(stderr,"Starting...\n"); /* goes to log file */
while (1) /* accept connection, deal with it, repeat */
{
fromLength=sizeof(from);
newsock=accept(sock,(struct sockaddr*)&from,&fromLength);
if (newsock==-1)
{
perror("Cannot accept connection");
continue;
}
remotehost = gethostbyaddr(&from.sin_addr, sizeof(from.sin_addr), AF_INET);
remotehostname = remotehost ? remotehost->h_name : "unknown";
fprintf(stderr,"Accepting connection from %s on port %d\n",
remotehostname, from.sin_port); /* need to convert ntohl ? */
switch (child=fork())
{
case -1:
perror("Cannot create child process to handle call");
break;
case 0: /* child - handle stdin and sockout */
while (1)
{
if (read_from_stdin(inbyte)==0)
{
close(newsock);
signal(getppid(),SIGUSR1); /* interrupt read */
EXIT(1);
}
if (write_to_socket(newsock, inbyte)==0) EXIT(1);
}
break;
default: /* parent - handle stdout and sockin */
Term_Raw(0);
while(1)
{
if (read_from_socket(newsock, outbyte)==0)
{
*outbyte = ESCAPE;
write_to_stdout(outbyte);
*outbyte = CMD_LOGOUT;
write_to_stdout(outbyte);
break;
}
if (*outbyte == ESCAPE)
{
/* Send it twice */
if (write_to_stdout(outbyte)==0) break;
}
if (*outbyte == 255)
{
if (read_from_socket(newsock, outbyte)==0) break;
if (*outbyte == 253)
{
if (read_from_socket(newsock, outbyte)==0) break;
/* finally we have a telnet command code */
telnet_command(*outbyte);
continue;
}
else
{
*outbyte=255;
if (write_to_stdout(outbyte)==0) break;
*outbyte=253;
if (write_to_stdout(outbyte)==0) break;
}
}
if (write_to_stdout(outbyte)==0) break;
}
kill(child,SIGKILL);
Term_Restore(0,&termbuf);
Term_NoEcho(0);
break;
} /* end switch */
} /* end while */
return(0);
}